﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web;

namespace API.Core.AuthorizeAttribute
{
    public class BasicHttpAuthorizeAttribute : System.Web.Http.AuthorizeAttribute
    {
        public bool RequireSsl
        {
            get { return true; }
        }

        public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
        {
            if (!Authenticate(actionContext))
                HandleUnauthorizedRequest(actionContext);
        }

        protected override void HandleUnauthorizedRequest(System.Web.Http.Controllers.HttpActionContext actionContext)
        {
            var challengeMessage = new System.Net.Http.HttpResponseMessage(HttpStatusCode.Unauthorized);
            challengeMessage.Headers.Add("WWW-Authenticate", "Basic");

            throw new System.Web.Http.HttpResponseException(challengeMessage);
        }

        private bool Authenticate(System.Web.Http.Controllers.HttpActionContext actionContext)
        {
            if (RequireSsl && !System.Web.HttpContext.Current.Request.IsSecureConnection && !System.Web.HttpContext.Current.Request.IsLocal)
            {
                return false;
            }

            if (!System.Web.HttpContext.Current.Request.Headers.AllKeys.Contains("Authorization")) return false;

            string authHeader = System.Web.HttpContext.Current.Request.Headers["Authorization"];

            System.Security.Principal.IPrincipal principal;
            if (TryGetPrincipal(authHeader, out principal))
            {
                System.Web.HttpContext.Current.User = principal;
                return true;
            }

            return false;
        }


        private bool TryGetPrincipal(string authHeader, out System.Security.Principal.IPrincipal principal)
        {
            var creds = AuthHelper.ParseAuthHeader(authHeader);

            if (creds != null)
            {
                if (TryGetPrincipal(creds[0], creds[1], out principal))
                    return true;
            }

            principal = null;
            return false;
        }

        bool TryGetPrincipal(string username, string password, out System.Security.Principal.IPrincipal principal)
        {
            principal = null;
            return true;
        }
    }

    class AuthHelper
    {
        public static string[] ParseAuthHeader(string authHeader)
        {
            if (string.IsNullOrEmpty(authHeader) || !authHeader.StartsWith("Basic")) return null;

            string base64Credentials = authHeader.Substring(6);
            var credentials = System.Text.Encoding.ASCII.GetString(Convert.FromBase64String(base64Credentials)).Split(new[] { ':' });

            if (credentials.Length != 2 || string.IsNullOrEmpty(credentials[0]) || string.IsNullOrEmpty(credentials[0])) return null;

            return credentials;
        }
    }
}